package com.lanjiu.lib.business.option;

import android.text.TextUtils;

import com.lanjiu.lib.NettyHost;
import com.lanjiu.lib.business.FileTransmissionManager;
import com.lanjiu.lib.utils.log.Logger;
import com.lanjiu.pro.file.FileTransmissionServiceGrpc;

import java.util.Vector;
import java.util.concurrent.TimeUnit;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

/**
 * @description:
 * @author: Panwei
 * @date: 2020/2/18 13:32
 */
public class FileTransmissionChannel {

    private static final int POOL_MAX = 10;
    private static Vector<FileTransmissionChannel> mFileTransmissionChannelPool;
    private static int mPoolIndexes;

    public synchronized static FileTransmissionChannel get() {
//        FileTransmissionChannel channel = null;
//        try {
        if (mFileTransmissionChannelPool == null) {
            mFileTransmissionChannelPool = new Vector<>();
            mFileTransmissionChannelPool.add(new FileTransmissionChannel(NettyHost.FILE_TRANSMISSION_HOST));
            mPoolIndexes = 0;
            return mFileTransmissionChannelPool.get(mPoolIndexes);
        }
        mPoolIndexes++;
        if (mPoolIndexes < POOL_MAX) {
            mFileTransmissionChannelPool.add(new FileTransmissionChannel(NettyHost.FILE_TRANSMISSION_HOST));
            return mFileTransmissionChannelPool.get(mPoolIndexes);
        } else {
            return mFileTransmissionChannelPool.get(mPoolIndexes % 10);
        }
//        } finally {
//            Logger.print("FileTransmissionChannel", "[INDEX] " + mPoolIndexes + " [POOL INDEX] " + (mPoolIndexes < POOL_MAX ? mPoolIndexes : mPoolIndexes % 10) + " [POOL SIZE] " + (mFileTransmissionChannelPool != null ? mFileTransmissionChannelPool.size() : 0));
//            if (channel != null)
//                Logger.print("FileTransmissionChannel", channel.mManagedChannel);
//        }
    }

    public static void shutdownAll() {
        mPoolIndexes = 0;
        if (mFileTransmissionChannelPool != null) {
            for (FileTransmissionChannel channel : mFileTransmissionChannelPool) {
                channel.shutdownNow();
            }
            mFileTransmissionChannelPool.clear();
        }
        mFileTransmissionChannelPool = null;
    }

    private ManagedChannel mManagedChannel;
    private FileTransmissionServiceGrpc.FileTransmissionServiceBlockingStub mFileTransmissionService;
    private String mAddress;

    private FileTransmissionChannel(String address) {
        mAddress = address;
        connect();
    }

    private void connect() {
        if (TextUtils.isEmpty(mAddress))
            throw new IllegalArgumentException("The fileTransmissionManager address cannot be 'null' or ''");

        String[] mHostAndPort = mAddress.split(":");
        if (mHostAndPort.length < 2)
            throw new IllegalArgumentException("The fileTransmissionManager address format should be 'host:port'");
        String host = mHostAndPort[0];
        int port;
        try {
            port = Integer.parseInt(mHostAndPort[1]);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("The port must be numeric");
        }
        if (mManagedChannel != null)
            shutdownNow();
        mManagedChannel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();
        mFileTransmissionService = FileTransmissionServiceGrpc.newBlockingStub(mManagedChannel);
    }

    void reconnect() {
        connect();
    }

    FileTransmissionServiceGrpc.FileTransmissionServiceBlockingStub service() {
        return mFileTransmissionService;
    }

    void shutdown() {
        if (mManagedChannel != null) {
            try {
                mManagedChannel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
            } catch (InterruptedException ignored) {
            }
            mManagedChannel = null;
        }
    }

    void shutdownNow() {
        if (mManagedChannel != null) {
            try {
                mManagedChannel.shutdownNow().awaitTermination(1, TimeUnit.SECONDS);
            } catch (InterruptedException ignored) {
            }
            mManagedChannel = null;
        }
    }
}
